package prototcp

import (
	"strconv"
	"strings"
	"sync/atomic"

	"gitee.com/crack007/proxy/src/proxy/protocol/logdump"

	"gitee.com/crack007/proxy/src/apputil"

	"gitee.com/crack007/proxy/src/constant"

	"gitee.com/crack007/goose/gscore/server"
	"gitee.com/crack007/goose/gslog"
)

var tcpId int64

type Tcp struct {
	sessionId string
	Session   *server.Session
	Output    string
	target    string
}

func (t *Tcp) ProcessServer(serverSession *server.Client, data []byte) {
	gslog.Debug("[%s] %s, length: %d", t.sessionId,
		apputil.AddColor("Receive from-> ", constant.COLOR_GREEN)+serverSession.Host+":"+strconv.Itoa(int(serverSession.Port)),
		len(data),
	)
	t.outputData(data)
}

func (t *Tcp) ProcessClient(data []byte) {
	gslog.Debug("[%s] %s, length: %d", t.sessionId,
		apputil.AddColor("Send to-> ", constant.COLOR_YELLO)+t.target,
		len(data),
	)
	t.outputData(data)
}

func (t *Tcp) GetSessionId() string {
	return t.sessionId
}

func (t *Tcp) Init(session *server.Session) {
	t.Session = session
	t.sessionId = strconv.Itoa(int(atomic.AddInt64(&tcpId, 1)))
	t.target = t.Session.RemoteIp + ":" + strconv.Itoa(int(t.Session.RemotePort))
}

func (t *Tcp) transBytesToString(data []byte, output string) (string, error) {
	tcpOutput, err := GetTcpOutput(output)
	if err != nil {
		return "", err
	}
	return tcpOutput.ToString(data), nil
}

func (t *Tcp) outputData(data []byte) {
	if t.Output == "" {
		return
	}
	outputList := strings.Split(strings.ToUpper(t.Output), "|")
	for _, output := range outputList {
		outputString, err := t.transBytesToString(data, output)
		if err != nil {
			continue
		}
		logdump.Info("[%s] Output format: %s\r\n%s\r\n", t.sessionId, output, outputString)
	}
}
